The QuickTime 4 API contains a number of derivative functions that have been generated to help you implement callback functions across the various platforms on which QuickTime runs--Windows, Macintosh 68K, and Macintosh PowerPC.
For a given callback procedure of type TheCallbackProcPtr , the following additional API elements are defined:
TheCallbackUPP
uppTheCallbackProcInfo
NewTheCallbackProc
CallTheCallbackProc
To illustrate the use of these elements, consider the PlayMoviePreview function that is part of the QuickTime software. It accepts a callback procedure that it will call during preview playback:
void PlayMoviePreview (
Movie theMovie,
MoviePreviewCallOutUPP callOutProc,
long refcon);
The callback's prototype is given by MoviePreviewCallOutProcPtr :
typedef CALLBACK_API ( Boolean, MoviePreviewCallOutProcPtr ) ( long refcon );
This is the prototype of the function you would write for the Windows platform or the Macintosh 68K or PowerPC platforms to implement the callback.
In a 68K implementation of this callback, you could simply pass the address of the callback function directly to PlayMoviePreview , which would periodically call the callback function.
In a PowerPC implementation, however, you can't pass the address of a PowerPC procedure directly to PlayMoviePreview because PlayMoviePreview expects the address of a 68K routine. Instead, you must pass the address of a Universal Procedure Pointer (UPP). A UPP looks enough like a 68K procedure to be callable from 68K code--when one is called from PowerPC code using CallUniversalProc , the Macintosh Mixed Mode Manager does the right thing.
The type of the UPP is generated by the line:
typedef STACK_UPP_TYPE (MoviePreviewCallOutProcPtr) MoviePreviewCallOutUPP;
To tell the Mixed Mode Manager the number and size of the parameters passed to the callback (so it can transition between PowerPC and 68K code) a 4-byte "proc info" value must be generated:
enum { uppMoviePreviewCallOutProcInfo = 0x000000D0 };
/* pascal 1_byte Func(4_bytes) */
In this case, the proc info value indicates that the function accepts a single 4 byte parameter, returns a Boolean value (one byte in length), and uses the Pascal calling convention.
To allocate UPPs to pass to PlayMoviePreview , QuickTime defines a NewMoviePreviewCallOutProc utility routine:
#define NewMoviePreviewCallOutProc(userRoutine) (MoviePreviewCallOutUPP)NewRoutineDescriptor \
((ProcPtr)(userRoutine), uppMoviePreviewCallOutProcInfo, GetCurrentArchitecture())
This routine calls NewRoutineDescriptor with the address of the native PowerPC callback function and the uppMoviePreviewCallOutProcInfo just defined. This allocates a UPP on the system heap that can be passed to the PlayMoviePreview .
If native PowerPC code wants to call such a UPP, it can't just jump to it because it's not PowerPC code but rather a block of data describing where the procedure exists. Instead, it can use the generated CallMoviePreviewCallOutProc utility function:
#define CallMoviePreviewCallOutProc (userRoutine, refcon) \
CALL_ONE_PARAMETER_UPP ((userRoutine), uppMoviePreviewCallOutProcInfo, (refcon))
This routine uses CallUniversalProc to invoke the callback function.
On the Windows platform, there's no 68K code issue so all callbacks just use the address of the callback directly. The NewMoviePreviewCallOutProc and CallMoviePreviewCallOutProc routines are simply macros that return the procedure address and call the procedure directly. This is also true for 68K code.
| Next |